Un guide complet pour créer des transformateurs personnalisés dans scikit-learn pour des pipelines de machine learning robustes et réutilisables. Apprenez à améliorer vos flux de prétraitement des données et d'ingénierie des caractéristiques.
Pipeline de Machine Learning : Développement de Transformateurs Personnalisés avec Scikit-learn
Les pipelines de machine learning sont essentiels pour construire des modèles de machine learning robustes et maintenables. Scikit-learn (sklearn) fournit un framework puissant pour créer ces pipelines. Un composant clé de tout bon pipeline est la capacité d'effectuer des transformations de données personnalisées. Cet article explore le développement de transformateurs personnalisés dans scikit-learn, offrant un guide complet pour les data scientists et les ingénieurs en machine learning du monde entier.
Qu'est-ce qu'un Pipeline de Machine Learning ?
Un pipeline de machine learning est une séquence de composants de traitement de données qui sont enchaînés. Ces composants incluent généralement :
- Nettoyage des données : Gestion des valeurs manquantes, des valeurs aberrantes et des incohérences.
- Ingénierie des caractéristiques : Création de nouvelles caractéristiques à partir de celles existantes pour améliorer les performances du modèle.
- Sélection des caractéristiques : Sélection des caractéristiques les plus pertinentes pour le modèle.
- Entraînement du modèle : Entraînement d'un modèle de machine learning sur les données préparées.
- Évaluation du modèle : Évaluation des performances du modèle entraîné.
L'utilisation d'un pipeline offre plusieurs avantages, notamment :
- Reproductibilité : Assurer que les mêmes étapes de traitement des données sont appliquées de manière cohérente.
- Modularité : Décomposer le flux de travail de traitement des données en composants réutilisables.
- Maintenabilité : Faciliter la mise à jour et la maintenance du flux de travail de traitement des données.
- Déploiement simplifié : Rationaliser le processus de déploiement des modèles de machine learning.
Pourquoi des Transformateurs Personnalisés ?
Scikit-learn fournit une large gamme de transformateurs intégrés pour les tâches courantes de traitement des données. Cependant, dans de nombreux scénarios réels, vous devrez effectuer des transformations de données personnalisées spécifiques à vos données et à votre problème. C'est là que les transformateurs personnalisés entrent en jeu. Les transformateurs personnalisés vous permettent d'encapsuler votre logique de traitement de données personnalisée dans des composants réutilisables qui peuvent être intégrés de manière transparente dans un pipeline scikit-learn.
Par exemple, imaginez que vous travaillez avec des données clients d'une plateforme de commerce électronique mondiale. Vous pourriez avoir besoin de créer un transformateur personnalisé qui convertit les devises des transactions en une devise commune (par exemple, l'USD) en fonction des taux de change historiques. Ou, considérez un scénario impliquant des données de capteurs provenant d'appareils IoT dans différents pays ; vous pourriez construire un transformateur personnalisé pour normaliser les données en fonction des fuseaux horaires locaux et des unités de mesure.
Construire un Transformateur Personnalisé
Pour créer un transformateur personnalisé dans scikit-learn, vous devez créer une classe qui hérite de sklearn.base.BaseEstimator et sklearn.base.TransformerMixin. Votre classe doit implémenter deux méthodes :
fit(self, X, y=None): Cette méthode apprend tous les paramètres nécessaires à la transformation. Dans de nombreux cas, cette méthode retourne simplementself.transform(self, X): Cette méthode applique la transformation aux données.
Voici un exemple de base d'un transformateur personnalisé qui ajoute une valeur constante à chaque caractéristique :
from sklearn.base import BaseEstimator, TransformerMixin
import numpy as np
class AddConstantTransformer(BaseEstimator, TransformerMixin):
def __init__(self, constant=1):
self.constant = constant
def fit(self, X, y=None):
return self
def transform(self, X):
return X + self.constant
Décortiquons cet exemple :
- Importer les bibliothèques nécessaires :
BaseEstimator,TransformerMixindesklearn.baseetnumpypour les opérations numériques. - Définir la classe :
AddConstantTransformerhérite deBaseEstimatoretTransformerMixin. - Constructeur (
__init__) : Cette méthode initialise le transformateur avec une valeurconstant(par défaut 1). - Méthode
fit: Cette méthode retourne simplementself, car ce transformateur n'a pas besoin d'apprendre de paramètres à partir des données. - Méthode
transform: Cette méthode ajoute la valeurconstantà chaque élément des données d'entréeX.
Exemple d'Utilisation
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
X = np.array([[1, 2], [3, 4], [5, 6]])
pipeline = Pipeline([
('scaler', StandardScaler()),
('add_constant', AddConstantTransformer(constant=2))
])
X_transformed = pipeline.fit_transform(X)
print(X_transformed)
Cet exemple montre comment utiliser le AddConstantTransformer dans un pipeline. D'abord, les données sont mises à l'échelle avec StandardScaler, puis la constante est ajoutée à l'aide de notre transformateur personnalisé.
Développement Avancé de Transformateurs Personnalisés
Explorons maintenant des scénarios et des techniques plus avancés pour construire des transformateurs personnalisés.
Gestion des Caractéristiques Catégorielles
Les caractéristiques catégorielles sont un type de données courant en machine learning. Vous pouvez créer des transformateurs personnalisés pour effectuer diverses opérations sur les caractéristiques catégorielles, telles que l'encodage one-hot, l'encodage par label ou le hachage de caractéristiques.
Voici un exemple de transformateur personnalisé qui effectue un encodage one-hot sur des colonnes spécifiées :
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
class CategoricalEncoder(BaseEstimator, TransformerMixin):
def __init__(self, categorical_features=None):
self.categorical_features = categorical_features
self.encoder = None
def fit(self, X, y=None):
if self.categorical_features is None:
self.categorical_features = X.select_dtypes(include=['object']).columns
self.encoder = OneHotEncoder(handle_unknown='ignore', sparse_output=False)
self.encoder.fit(X[self.categorical_features])
return self
def transform(self, X):
X_encoded = self.encoder.transform(X[self.categorical_features])
X_encoded = pd.DataFrame(X_encoded, index=X.index, columns=self.encoder.get_feature_names_out(self.categorical_features))
X = X.drop(columns=self.categorical_features)
X = pd.concat([X, X_encoded], axis=1)
return X
Dans cet exemple :
- Le transformateur identifie automatiquement les colonnes catégorielles (si non spécifiées).
- Il utilise
OneHotEncoderde scikit-learn pour effectuer l'encodage. - Il gère les catégories inconnues avec
handle_unknown='ignore'. - Les caractéristiques encodées sont concaténées au dataframe d'origine.
Gestion des Valeurs Manquantes
Les valeurs manquantes sont un autre problème courant dans les jeux de données de machine learning. Vous pouvez créer des transformateurs personnalisés pour imputer les valeurs manquantes en utilisant diverses stratégies, telles que l'imputation par la moyenne, la médiane ou le mode.
Voici un exemple de transformateur personnalisé qui impute les valeurs manquantes en utilisant la médiane :
from sklearn.impute import SimpleImputer
class MissingValueImputer(BaseEstimator, TransformerMixin):
def __init__(self, strategy='median', missing_values=np.nan):
self.strategy = strategy
self.missing_values = missing_values
self.imputer = None
def fit(self, X, y=None):
self.imputer = SimpleImputer(strategy=self.strategy, missing_values=self.missing_values)
self.imputer.fit(X)
return self
def transform(self, X):
return self.imputer.transform(X)
Ce transformateur utilise SimpleImputer de scikit-learn pour effectuer l'imputation. Il vous permet de spécifier la stratégie d'imputation et la valeur utilisée pour représenter les valeurs manquantes.
Mise à l'Échelle et Normalisation des Caractéristiques
La mise à l'échelle et la normalisation des caractéristiques sont des étapes de prétraitement importantes pour de nombreux algorithmes de machine learning. Vous pouvez créer des transformateurs personnalisés pour implémenter différentes techniques de mise à l'échelle et de normalisation.
Bien que scikit-learn fournisse des transformateurs comme StandardScaler et MinMaxScaler, vous pourriez avoir besoin d'un scaler personnalisé pour des distributions de données spécifiques. Par exemple, si vous avez des données avec une distribution très asymétrique, un PowerTransformer (également disponible dans scikit-learn) pourrait être plus approprié. Cependant, vous pouvez l'encapsuler dans un transformateur personnalisé pour gérer ses paramètres et l'intégrer de manière transparente dans votre pipeline.
from sklearn.preprocessing import PowerTransformer
class SkewedDataTransformer(BaseEstimator, TransformerMixin):
def __init__(self, method='yeo-johnson'):
self.method = method
self.transformer = None
def fit(self, X, y=None):
self.transformer = PowerTransformer(method=self.method)
self.transformer.fit(X)
return self
def transform(self, X):
return self.transformer.transform(X)
Combinaison de Plusieurs Transformations
Parfois, vous devrez peut-être appliquer plusieurs transformations aux mêmes données. Vous pouvez créer un transformateur personnalisé qui combine plusieurs transformations en une seule étape. Cela peut aider à simplifier votre pipeline et à le rendre plus lisible.
Voici un exemple de transformateur personnalisé qui combine l'encodage one-hot et l'imputation de valeurs manquantes :
class CombinedTransformer(BaseEstimator, TransformerMixin):
def __init__(self, categorical_features=None, missing_value_strategy='median'):
self.categorical_features = categorical_features
self.missing_value_strategy = missing_value_strategy
self.categorical_encoder = None
self.missing_value_imputer = None
def fit(self, X, y=None):
self.categorical_encoder = CategoricalEncoder(categorical_features=self.categorical_features)
self.missing_value_imputer = MissingValueImputer(strategy=self.missing_value_strategy)
self.categorical_encoder.fit(X)
self.missing_value_imputer.fit(X)
return self
def transform(self, X):
X = self.categorical_encoder.transform(X)
X = self.missing_value_imputer.transform(X)
return X
Ce transformateur utilise le CategoricalEncoder et le MissingValueImputer des exemples précédents pour effectuer à la fois l'encodage one-hot et l'imputation de valeurs manquantes en une seule étape.
Meilleures Pratiques pour le Développement de Transformateurs Personnalisés
Voici quelques meilleures pratiques à suivre lors du développement de transformateurs personnalisés :
- Restez simple : Chaque transformateur doit effectuer une tâche unique et bien définie.
- Rendez-le réutilisable : Concevez vos transformateurs pour qu'ils soient aussi génériques que possible afin de pouvoir être réutilisés dans différents pipelines.
- Gérez les cas limites : Pensez à la manière dont votre transformateur gérera les cas limites, tels que les valeurs manquantes, les valeurs aberrantes et les types de données inattendus.
- Écrivez des tests unitaires : Écrivez des tests unitaires pour vous assurer que votre transformateur fonctionne correctement.
- Documentez votre code : Documentez clairement votre code afin que d'autres puissent comprendre comment utiliser votre transformateur.
Exemples du Monde Réel
Explorons quelques exemples plus concrets de transformateurs personnalisés.
Ingénierie de Caractéristiques de Date
Lorsque vous travaillez avec des données de séries temporelles, il est souvent utile d'extraire des caractéristiques à partir des dates, comme le jour de la semaine, le mois de l'année ou le trimestre de l'année. Vous pouvez créer un transformateur personnalisé pour effectuer cette tâche.
class DateFeatureExtractor(BaseEstimator, TransformerMixin):
def __init__(self, date_columns=None):
self.date_columns = date_columns
def fit(self, X, y=None):
return self
def transform(self, X):
for col in self.date_columns:
X[col + '_dayofweek'] = X[col].dt.dayofweek
X[col + '_month'] = X[col].dt.month
X[col + '_quarter'] = X[col].dt.quarter
return X
Ce transformateur extrait le jour de la semaine, le mois et le trimestre des colonnes de date spécifiées.
Ingénierie de Caractéristiques Textuelles
Lorsque vous travaillez avec des données textuelles, il est souvent utile de faire de l'ingénierie de caractéristiques en utilisant des techniques telles que TF-IDF ou les plongements de mots (word embeddings). Vous pouvez créer des transformateurs personnalisés pour effectuer ces tâches. Par exemple, considérez les avis de clients dans plusieurs langues. Vous pourriez avoir besoin d'un transformateur personnalisé qui traduit les avis en anglais avant d'appliquer la vectorisation TF-IDF.
Note : Les services de traduction nécessitent souvent des clés API et peuvent entraîner des coûts. Cet exemple se concentre sur la structure du transformateur personnalisé.
# Note : Cet exemple nécessite un service de traduction (par ex., Google Translate API) et une clé API
# from googletrans import Translator # Bibliothèque d'exemple (à installer avec pip install googletrans==4.0.0-rc1)
class TextFeatureExtractor(BaseEstimator, TransformerMixin):
def __init__(self, text_column, language='en'):
self.text_column = text_column
self.language = language
# self.translator = Translator() # Instancier le traducteur (nécessite une configuration)
def fit(self, X, y=None):
return self
def transform(self, X):
# Exemple : Traduire en anglais (à remplacer par la logique de traduction réelle)
# X[self.text_column + '_translated'] = X[self.text_column].apply(lambda text: self.translator.translate(text, dest=self.language).text)
# Traduction factice pour la démonstration
X[self.text_column + '_translated'] = X[self.text_column].apply(lambda text: "Translated: " + text)
# Appliquer TF-IDF ou d'autres techniques de vectorisation de texte ici
return X
Ingénierie de Caractéristiques Géospatiales
Lorsque vous travaillez avec des données géospatiales, vous pouvez créer des transformateurs personnalisés pour extraire des caractéristiques telles que la distance à la ville la plus proche, la densité de population ou le type d'utilisation des sols. Par exemple, considérez l'analyse des prix de l'immobilier à l'échelle mondiale. Vous pourriez créer un transformateur personnalisé qui récupère le niveau de revenu moyen pour un emplacement donné en utilisant des API externes basées sur la latitude et la longitude.
Intégration avec les Bibliothèques Existantes
Les transformateurs personnalisés peuvent être utilisés pour encapsuler les fonctionnalités d'autres bibliothèques Python dans un pipeline scikit-learn. Cela vous permet de tirer parti de la puissance d'autres bibliothèques tout en bénéficiant de la structure et de l'organisation d'un pipeline.
Par exemple, vous pourriez utiliser un transformateur personnalisé pour intégrer une bibliothèque de détection d'anomalies, de prévision de séries temporelles ou de traitement d'images dans votre pipeline de machine learning.
Conclusion
Les transformateurs personnalisés sont un outil puissant pour construire des pipelines de machine learning robustes et maintenables dans scikit-learn. En encapsulant votre logique de traitement de données personnalisée dans des composants réutilisables, vous pouvez créer des pipelines plus faciles à comprendre, à mettre à jour et à déployer. N'oubliez pas de suivre les meilleures pratiques, d'écrire des tests unitaires et de documenter votre code pour garantir que vos transformateurs personnalisés sont fiables et maintenables. À mesure que vous développerez vos compétences en machine learning, la maîtrise du développement de transformateurs personnalisés deviendra inestimable pour aborder des problèmes complexes et variés du monde réel à travers le globe. De la gestion des conversions de devises pour le commerce électronique international au traitement des données de capteurs d'appareils IoT dans le monde entier, les transformateurs personnalisés vous permettent d'adapter vos pipelines aux besoins spécifiques de vos données et de vos applications.